#include <stdio.h>
#include <stdlib.h>
#include <assert.h>

#include <compl.h>
#include <dbg.h>

/* 尝试 */
//__builtin_call_with_static_chain
// __builtin_choose_expr
/* 如果能推导出来就用trap */
/* 成功之后就能把assert改成假设 */
/* 能推导出来-> 在编译时就给出告警或者 */
// #define NULL_REFERENCE_ERROR()		char *p = NULL; *p = NULL

// PARAM_NONULL(1) SAI void *__null_ref_error (const void *ptr) {
//	 // if (!ptr) return (*(void **)ptr);
//	 return NULL;
// }
// else { ASSUME(cond);}
#define __CONST_ASSERT(cond)	if(!(cond)) { NULL_REFERENCE_ERROR(); }
#define CONST_ASSERT(cond)	  { const char *__tmp_assert__ = TIF_ELSE(CAN_EVAL(cond), (cond) ? #cond : (const char *)0, (void)0 );}\

/* 如果编译时能推导出来->给出告警 */


#define STATIC_ASSERT(COND,MSG) static int static_assertion_##MSG[(COND)?1:-1]

int main(){
	int a = 0;
	// TIF_ELSE(a == 0, (void)0, assert(a==0));
	// else assert(a == 0);
	/* 如果能推导*/
	int c = CAN_EVAL(a == 0);
	// printf("%d\n", c);
	// assert(c == 1);
	// STATIC_ASSERT(a == 0, WTF);
	ASSERT(c == 1);
	if (CAN_EVAL(a == 0) && !(a == 0)) {
	int d = (a==0);
	ASSERT(d==1);
	}
	INFO("all ok\n");
	// CONST_ASSERT(a == 0);
	// CONST_ASSERT(a == 1);
}
